#include <stdio.h>  //for NULL
#include <stdlib.h> // for malloc
#include <string.h> //for memset
#include "queue.h"

// return QUEUE_FAIL if malloc error
int init(queue_t *queuePtr, int capacity) {
    if (capacity > 0) {
        queuePtr->elements = (int *)malloc(capacity*sizeof(int));
        if (queuePtr->elements == NULL) return QUEUE_FAIL;

        memset(queuePtr->elements, -1, capacity*sizeof(int));
        queuePtr->front = 0;
        queuePtr->size = 0;
        queuePtr->capacity = capacity;
        
        return QUEUE_OK;
    }
    return QUEUE_FAIL;
} 

//return 1 if queue is full
int isFULL(queue_t *queuePtr) {
    return (queuePtr>0 && (queuePtr->size >= queuePtr->capacity));  
}  

// return 1 if queue is empty
int isEmpty(queue_t *queuePtr){ 
    return (queuePtr->size == 0);
}


//return QUEUE_FULL if error
int enqueue(queue_t *queuePtr, int x) {
    if (!isFULL(queuePtr)) {
        int rear = (queuePtr->front+queuePtr->size)%queuePtr->capacity;
        queuePtr->elements[rear] = x;
        queuePtr->size++;
        return QUEUE_OK;
    }
    return QUEUE_FULL;
}

// retVaule =  front of queue and return QUEUE_OK if queue is not empty, 
// otherwise return QUEUE_EMPTY
int dequeue(queue_t *queuePtr, int* retValue) {
    if (!isEmpty(queuePtr)) {
        *retValue = queuePtr->elements[queuePtr->front];
        queuePtr->front = (queuePtr->front+1)%queuePtr->capacity;
        queuePtr->size--;
        return QUEUE_OK;
    }
    return QUEUE_EMPTY;
}

// return 1 if x is contained in queue
int isExist(queue_t *queuePtr, int x) {
    int i=queuePtr->front;
    int end = (queuePtr->front+queuePtr->size)%queuePtr->capacity;
    while(i != end) {
        if (queuePtr->elements[i] == x) 
            return 1;
        i++;
    }
    return 0;
}